package fun.codedesign.jdk.thread;


import org.junit.Test;

import java.util.Calendar;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


/**
 * lock 和 sync
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author zengjian
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class LockAndSync implements Runnable {
    private final Lock lock = new ReentrantLock();
    private String str = "init";

    public static void main(String[] args) {
//		Advice127_LockAndSync entity = new Advice127_LockAndSync();
//		entity.method01();
//		entity.method02();

//		ExecutorService pool = Executors.newCachedThreadPool();
//		for (int i = 0; i < 5; i++) {
//			pool.submit(new Advice127_LockAndSync());
//		}

        // lock定义为多线程类的私有属性是无法作用到资源互斥的作用的
        final Lock lock = new ReentrantLock();

        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        lock.lock();
                        Thread.sleep(2000);
                        System.out.println(System.nanoTime());
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
            }).start();
        }


    }

    @Override
    public void run() {
        try {
            //synchronized ("A") {
            lock.lock();
            Thread.sleep(2000);
            System.out.println("线程" + Thread.currentThread().getName() + " 时间：" + Calendar.getInstance().get(Calendar.MILLISECOND));
            System.out.println(str += Thread.currentThread().getName());
            //}
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public void method01() {
        try {
            lock.lock();
            System.out.println("123");
            str += "123";
            System.out.println(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void method02() {
        try {
            lock.lock();
            System.out.println("方法2");
            str += "method02";
            System.out.println(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testThread() throws Exception {

        final ThreadFoo foo = new ThreadFoo();

        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    foo.write();
                }
            }).start();
        }
    }


}


class ThreadFoo {
    private final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
    private final Lock r = rw.readLock();
    private final Lock w = rw.writeLock();

    public void read() {
        try {
            r.lock();
            Thread.sleep(1000);
            System.out.println("读取.....");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            r.unlock();
        }
    }

    public void write() {
        try {
            w.lock();
            Thread.sleep(1000);
            System.out.println("写操作...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            w.unlock();
        }
    }

}
